"""DNS区域管理."""

from typing import List, Optional

from sqlalchemy import select, and_
from sqlalchemy.ext.asyncio import AsyncSession

from netsphere.models.dns import DNSRecord, DNSZone


class ZoneManager:
    """DNS区域管理器."""
    
    def __init__(self, session: AsyncSession):
        """初始化区域管理器.
        
        Args:
            session: 数据库会话
        """
        self.session = session
    
    async def get_zone_stats(self, zone_id: int) -> dict:
        """获取区域统计信息.
        
        Args:
            zone_id: 区域ID
            
        Returns:
            统计信息字典
        """
        query = select(DNSRecord).where(DNSRecord.zone_id == zone_id)
        result = await self.session.execute(query)
        records = list(result.scalars().all())
        
        stats = {
            "total_records": len(records),
            "record_types": {},
            "active_records": 0,
            "inactive_records": 0,
        }
        
        for record in records:
            record_type = record.record_type
            stats["record_types"][record_type] = stats["record_types"].get(record_type, 0) + 1
            
            if record.is_active:
                stats["active_records"] += 1
            else:
                stats["inactive_records"] += 1
        
        return stats
    
    async def get_zone_soa(self, zone_id: int) -> Optional[dict]:
        """获取区域的SOA记录信息.
        
        Args:
            zone_id: 区域ID
            
        Returns:
            SOA记录信息或None
        """
        zone = await self.session.get(DNSZone, zone_id)
        if not zone:
            return None
        
        return {
            "primary_ns": zone.primary_ns,
            "admin_email": zone.admin_email,
            "serial": zone.serial,
            "refresh": zone.refresh,
            "retry": zone.retry,
            "expire": zone.expire,
            "minimum": zone.minimum_ttl,
        }
    
    async def validate_zone_config(self, zone_id: int) -> dict:
        """验证区域配置.
        
        Args:
            zone_id: 区域ID
            
        Returns:
            验证结果字典
        """
        zone = await self.session.get(DNSZone, zone_id)
        if not zone:
            return {"valid": False, "errors": ["Zone not found"]}
        
        errors = []
        warnings = []
        
        # 检查必需的NS记录
        ns_query = select(DNSRecord).where(
            and_(
                DNSRecord.zone_id == zone_id,
                DNSRecord.record_type == "NS"
            )
        )
        result = await self.session.execute(ns_query)
        ns_records = list(result.scalars().all())
        
        if not ns_records:
            errors.append("Missing NS records for zone")
        
        # 检查根A记录
        if zone.name != ".":
            root_a_query = select(DNSRecord).where(
                and_(
                    DNSRecord.zone_id == zone_id,
                    DNSRecord.name == zone.name,
                    DNSRecord.record_type == "A"
                )
            )
            result = await self.session.execute(root_a_query)
            root_a_records = list(result.scalars().all())
            
            if not root_a_records:
                warnings.append("No A record for zone root")
        
        # 检查CNAME冲突
        cname_query = select(DNSRecord).where(
            and_(
                DNSRecord.zone_id == zone_id,
                DNSRecord.record_type == "CNAME"
            )
        )
        result = await self.session.execute(cname_query)
        cname_records = list(result.scalars().all())
        
        for cname in cname_records:
            # 检查同名的其他记录
            conflict_query = select(DNSRecord).where(
                and_(
                    DNSRecord.zone_id == zone_id,
                    DNSRecord.name == cname.name,
                    DNSRecord.record_type != "CNAME"
                )
            )
            result = await self.session.execute(conflict_query)
            conflicts = list(result.scalars().all())
            
            if conflicts:
                errors.append(
                    f"CNAME record '{cname.name}' conflicts with other records"
                )
        
        return {
            "valid": len(errors) == 0,
            "errors": errors,
            "warnings": warnings,
        }
    
    async def export_zone(self, zone_id: int) -> str:
        """导出区域配置为BIND格式.
        
        Args:
            zone_id: 区域ID
            
        Returns:
            BIND格式的区域配置
        """
        zone = await self.session.get(DNSZone, zone_id)
        if not zone:
            return ""
        
        # 获取所有记录
        query = select(DNSRecord).where(
            DNSRecord.zone_id == zone_id
        ).order_by(DNSRecord.name, DNSRecord.record_type)
        
        result = await self.session.execute(query)
        records = list(result.scalars().all())
        
        # 生成区域文件内容
        zone_content = f"""$TTL {zone.minimum_ttl}
$ORIGIN {zone.name}.

; SOA记录
@ IN SOA {zone.primary_ns}. {zone.admin_email}. (
    {zone.serial} ; Serial
    {zone.refresh} ; Refresh
    {zone.retry} ; Retry
    {zone.expire} ; Expire
    {zone.minimum_ttl} ; Minimum TTL
)

; NS记录
"""
        
        # 添加NS记录
        ns_records = [r for r in records if r.record_type == "NS"]
        for ns in ns_records:
            zone_content += f"{ns.name} IN NS {ns.value}.\n"
        
        zone_content += "\n; 其他记录\n"
        
        # 添加其他记录
        for record in records:
            if record.record_type == "NS":
                continue
            
            if record.record_type in ["A", "AAAA", "TXT"]:
                zone_content += f"{record.name} IN {record.record_type} {record.value}\n"
            elif record.record_type == "CNAME":
                zone_content += f"{record.name} IN CNAME {record.value}.\n"
            elif record.record_type == "MX":
                zone_content += f"{record.name} IN MX {record.priority} {record.value}.\n"
        
        return zone_content